/*
 * Copyright (c) 2016. @huishenghuo.inf,Co,Limitid.
 */

package com.xiaoq.users.service;


import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.xiaoq.coms.RestException;
import com.xiaoq.coms.util.ConstantUtil;
import com.xiaoq.coms.util.DigestUtil;
import com.xiaoq.coms.util.IdGenerator;
import com.xiaoq.coms.util.JsonUtil;
import com.xiaoq.user.endpoint.ThirdLoginVo;
import com.xiaoq.user.endpoint.ThirdRegisterVo;
import com.xiaoq.users.entity.ThirdAccountInfoEntity;
import com.xiaoq.users.entity.UserEntity;
import com.xiaoq.users.entity.UserTermDeviceEntity;
import com.xiaoq.users.redis.RedisTemplate4JedisCluster;
import com.xiaoq.users.repository.UserRepository;
import com.xiaoq.users.service.exception.AuthenFailException;
import com.xiaoq.users.service.exception.UserAlreadyExistException;
import com.xiaoq.users.service.exception.UserNotFoundException;


/**
 * @author wang zhihao created on 2018/4/12.
 */
@Service
public class AccountService {

    private static Logger logger = LoggerFactory.getLogger(AccountService.class);

    @Autowired
    private UserRepository userRepo;

    @Autowired
    private IdGenerator idGenerator;
    
    @Autowired
	private RedisTemplate4JedisCluster redisTemplate;
    
    @Autowired
    private TencentIMService tencentIMService;
    
    private static final Logger LOG = LoggerFactory.getLogger(AccountService.class);

    public UserEntity createByCellphoneNumber(UserEntity userEntity) {

        if (userRepo.findByLoginAccount(userEntity.getAccount()) != null) {
            throw new UserAlreadyExistException();
        }    
        userEntity.setId(idGenerator.nextId());
        userEntity.setCreatedAt(System.currentTimeMillis());
        userEntity.setUpdatedAt(System.currentTimeMillis());
        userEntity.setSalt(idGenerator.nextId());
        entryptPassword(userEntity, userEntity.getPasswd());
        
        userEntity.setUserRoleList(Arrays.asList(new UserEntity.Role[] {UserEntity.Role.USER}));
        userEntity.setRegMethod(UserEntity.RegMethod.MOBILE);

        userEntity.setAccount(userEntity.getMobile());
        
        //向腾讯IM注册一个用户
        TencentRequestVo tencenRequestVo = new TencentRequestVo();
        tencenRequestVo.setIdentifier(userEntity.getId());
        tencenRequestVo.setNick(userEntity.getNickName());
        tencenRequestVo.setFaceUrl(userEntity.getLogoUrl());
        TencentResponseVo tencentResponse = tencentIMService.tencentAccount(tencenRequestVo);
        
        return userRepo.save(userEntity);
    }


    /**
     * 根据手机号修改密码
     * @param password
     * @param mobile
     * @return
     */
    public boolean passwordByMobil(String password,String mobile){
    	UserEntity userEntityInDB = userRepo.findByMobile(mobile);
    	
    	if (userEntityInDB == null) {
        	throw new UserNotFoundException("找不到用户");
        }
		entryptPassword(userEntityInDB, password);

		 //向腾讯IM注册一个用户
        TencentRequestVo tencenRequestVo = new TencentRequestVo();
        tencenRequestVo.setIdentifier(userEntityInDB.getId());
        tencenRequestVo.setNick(userEntityInDB.getNickName());
        tencenRequestVo.setFaceUrl(userEntityInDB.getLogoUrl());
        TencentResponseVo tencentResponse = tencentIMService.tencentAccount(tencenRequestVo);
		
		userRepo.save(userEntityInDB);
        return true;
    	
    }
    public UserEntity loginByMobileAndPasswd(String mobile, String passwd, UserTermDeviceEntity termDevice) {
        UserEntity userInDB;
        userInDB = userRepo.findByLoginAccount(mobile);
        if (userInDB == null) {
        	throw new AuthenFailException();
        }
        if (!isValidPassword(userInDB, passwd)) {
        	throw new AuthenFailException();
        } 
        if (termDevice != null) {
        	// @TODO 使用正式账号登录后将原有匿名账号删除，匿名账号的行为需要迁移？
        	List<UserEntity> anonymousList = userRepo.findAnonymousByTerm(termDevice);
        	if (anonymousList != null && anonymousList.size() > 0) {
        		for (UserEntity an : anonymousList) {
        			userRepo.remove(an);
        		}
        	}
        	updateLastLoginedDeviceInfoInUserEntityAndMemberEntity(userInDB, termDevice);
        }
      //向腾讯IM注册一个用户
//        TencentRequestVo tencenRequestVo = new TencentRequestVo();
//        tencenRequestVo.setIdentifier(userInDB.getId());
//        tencenRequestVo.setNick(userInDB.getNickName());
//        tencenRequestVo.setFaceUrl(userInDB.getLogoUrl());
//        TencentResponseVo tencentResponse = tencentIMService.tencentAccount(tencenRequestVo);
        return userRepo.save(userInDB);

    }

    private void updateLastLoginedDeviceInfoInUserEntityAndMemberEntity(UserEntity userInDB, UserTermDeviceEntity termDevice) {
    	UserTermDeviceEntity termDeviceInDB = userInDB.getTermDevice();
    	long curTime = System.currentTimeMillis();
    	if (termDeviceInDB == null) {
    		termDeviceInDB = new UserTermDeviceEntity();
    		termDeviceInDB.setId(idGenerator.nextId());
    		termDeviceInDB.setCreatedAt(curTime);
    		userInDB.setTermDevice(termDeviceInDB);
    	}
    	BeanUtils.copyProperties(termDevice, termDeviceInDB);
    	termDeviceInDB.setUpdatedAt(curTime);
            
        //memberManagerService4dubbox.updateLastLoginedDeviceInfoByCellphoneNumber(
        //        userEntity.getCellphoneNumber(),
        //        userEntity.getMobileDeviceEntity().getRegId(),
        //        userEntity.getMobileDeviceEntity().getOsType());
    }

    public UserEntity loginByThirdOpenId(ThirdLoginVo thirdLoginVo) {
        UserEntity userInDB;

        userInDB = userRepo
                .findByThirdPlatformTypeAndThirdOpenId(thirdLoginVo.getThirdAccountType(),thirdLoginVo.getThirdAccount());

        if (userInDB == null) {
        	throw new AuthenFailException();
        }

        //updateLastLoginedDeviceInfoInUserEntityAndMemberEntity(userInDB, null);

        String thirdAccount = thirdLoginVo.getThirdAccount();
        String session_key = redisTemplate.get(ConstantUtil.WEIXINUNIONID_SESSIONKEY, thirdAccount);
        List<ThirdAccountInfoEntity> thirdAccountList =  userInDB.getThirdAccountList();
        for(ThirdAccountInfoEntity thirdAccountInfo: thirdAccountList){
        	String thirdType = thirdAccountInfo.getThirdAccountType();
        	if(thirdType.equals("WEIXIN")){
        		thirdAccountInfo.setSession_key(session_key);
        	}
        }
        
        return userRepo.save(userInDB);

    }


    /**
	 * 微信小程序登陆
	 *
	 * */
	public UserEntity loginByWechatOpenId(ThirdLoginVo thirdLoginVo){
		UserEntity userInDB;

		userInDB = userRepo
				.findByThirdPlatformTypeAndThirdOpenId(thirdLoginVo.getThirdAccountType(),thirdLoginVo.getThirdAccount());

		if(null == userInDB){
			//insert
			userInDB =new UserEntity();
			userInDB.setId(idGenerator.nextId());
			userInDB.setCreatedAt(System.currentTimeMillis());
			userInDB.setUpdatedAt(System.currentTimeMillis());
			List<ThirdAccountInfoEntity> thirdAccountList = new ArrayList<>();
			ThirdAccountInfoEntity thirdAccountInfoEntity = new ThirdAccountInfoEntity();
			thirdAccountInfoEntity.setThirdAccount(thirdLoginVo.getThirdAccount());
			thirdAccountInfoEntity.setThirdAccountType(thirdLoginVo.getThirdAccountType());
			thirdAccountList.add(thirdAccountInfoEntity);
			userInDB.setThirdAccountList(thirdAccountList);
			return userRepo.save(userInDB);
		}
		return userInDB;

	}


    public UserEntity loginByMobileAndSmsCode(String cellphoneNumber, String verificationCode, String currentLoginIp) {
        UserEntity userInDB;
        userInDB = userRepo.findByLoginAccount(cellphoneNumber);
        if (userInDB == null) {
        	throw new AuthenFailException();
        }

        userInDB.setLastLoginTime(System.currentTimeMillis());

        return userRepo.save(userInDB);
    }

    //手机号注册第2步
    public UserEntity updateById(String userId, String nickName, int gender, String birthDate) {
        UserEntity userEntityInDB = userRepo.getById(userId);

        if (userEntityInDB == null) {
            throw new UserNotFoundException();
        }
        userEntityInDB.setNickName(nickName);
        userEntityInDB.setGender(gender);

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            userEntityInDB.setBirthday(sdf.parse(birthDate).getTime());
        } catch (java.text.ParseException pae) {
            throw new RestException(HttpStatus.BAD_REQUEST, "生日格式不对");
        }

        
        //向腾讯IM注册一个用户
        TencentRequestVo tencenRequestVo = new TencentRequestVo();
        tencenRequestVo.setIdentifier(userEntityInDB.getId());
        tencenRequestVo.setNick(userEntityInDB.getNickName());
        tencenRequestVo.setFaceUrl(userEntityInDB.getLogoUrl());
        TencentResponseVo tencentResponse = tencentIMService.tencentAccount(tencenRequestVo);
        return userRepo.save(userEntityInDB);

    }


    /**
     * 
     * @param thirdRegisterVo
     * @return
     */
	public UserEntity registerOrBindingCellphoneByThirdOpenId(ThirdRegisterVo thirdRegisterVo) {

		// 百川注册需要密码我只能给他默认初始化一个
		UserEntity userEntity = new UserEntity();
		userEntity.setPasswd(idGenerator.nextId());
		UserEntity userEntityInDB = userRepo.findByLoginAccount(thirdRegisterVo.getMobile());

		if (userEntityInDB != null) { // 说明已经通过手机号单独注册过了,因此直接Update用手机号注册过的那条记录
			List<ThirdAccountInfoEntity> thirdAccountList = userEntityInDB.getThirdAccountList();
			if (thirdAccountList == null || thirdAccountList.size() == 0) { // 手机号没有绑定第三方用户
				thirdAccountList = new ArrayList<>();

			}

			ThirdAccountInfoEntity thirdAccount = new ThirdAccountInfoEntity();
			thirdAccount.setId(idGenerator.nextId());
			BeanUtils.copyProperties(thirdRegisterVo, thirdAccount);
			thirdAccountList.add(thirdAccount);
			userEntityInDB.setTermDevice(thirdRegisterVo.getTermDevice());
			userEntityInDB.setGender(thirdRegisterVo.getGender());
			userEntityInDB.setThirdAccountList(thirdAccountList);
			return userRepo.save(userEntityInDB);

		} else { // 说明手机号没有单独注册过账户

			logger.debug("birthDate = " + userEntity.getBirthday());
			BeanUtils.copyProperties(thirdRegisterVo, userEntity);
			List<ThirdAccountInfoEntity> thirdAccountList = new ArrayList<>();
			ThirdAccountInfoEntity thirdAccount = new ThirdAccountInfoEntity();
			String thAccount = thirdRegisterVo.getThirdAccount();
			thirdAccount.setId(idGenerator.nextId());
			thirdAccount.setThirdAccount(thirdRegisterVo.getThirdAccount());
			thirdAccount.setThirdAccountType(thirdRegisterVo.getThirdAccountType());
			thirdAccount.setThirdInfo(thirdRegisterVo.getThirdInfo());
			thirdAccount.setThirdNickName(thirdRegisterVo.getThirdNickName());
			thirdAccount.setThirdLogo(thirdRegisterVo.getThirdLogoUrl());
			thirdAccount.setSession_key(redisTemplate.get(ConstantUtil.WEIXINUNIONID_SESSIONKEY, thAccount));
			thirdAccountList.add(thirdAccount);

			userEntity.setUserRoleList(Arrays.asList(new UserEntity.Role[] { UserEntity.Role.USER }));
			userEntity.setRegMethod(UserEntity.RegMethod.valueOf(thirdAccount.getThirdAccountType()));
			userEntity.setId(idGenerator.nextId());
			userEntity.setSalt(idGenerator.nextId());
			userEntity.setThirdAccountList(thirdAccountList);
			entryptPassword(userEntity, userEntity.getPasswd());

			userEntity.setNickName(thirdRegisterVo.getThirdNickName());
			userEntity.setLogoUrl(thirdRegisterVo.getThirdLogoUrl());
			userRepo.save(userEntity);
			
			 //向腾讯IM注册一个用户
	        TencentRequestVo tencenRequestVo = new TencentRequestVo();
	        tencenRequestVo.setIdentifier(userEntity.getId());
	        tencenRequestVo.setNick(userEntity.getNickName());
	        tencenRequestVo.setFaceUrl(userEntity.getLogoUrl());
	        TencentResponseVo tencentResponse = tencentIMService.tencentAccount(tencenRequestVo);
			return userEntity;
		}
	}

    @Transactional
    public UserEntity changePassword(String userId,String newPasswd){
        UserEntity userEntityInDB = userRepo.getById(userId);
        if (userEntityInDB == null) {
        	throw new UserNotFoundException("找不到用户");
        }
		entryptPassword(userEntityInDB, newPasswd);

		
		 //向腾讯IM注册一个用户
        TencentRequestVo tencenRequestVo = new TencentRequestVo();
        tencenRequestVo.setIdentifier(userEntityInDB.getId());
        tencenRequestVo.setNick(userEntityInDB.getNickName());
        tencenRequestVo.setFaceUrl(userEntityInDB.getLogoUrl());
        TencentResponseVo tencentResponse = tencentIMService.tencentAccount(tencenRequestVo);
		
		return userRepo.save(userEntityInDB);

    }

    public void logout(Long userId) {
    	// @Todo
    }

    private void entryptPassword(UserEntity user, String password) {
        user.setPasswd(DigestUtil.md5(password + "{" + user.getSalt() + "}"));
    }

    private boolean isValidPassword(UserEntity user, String password) {
        String entryptPassword = DigestUtil.md5(password + "{" + user.getSalt() + "}");
        return user.getPasswd().equals(entryptPassword);
    }

	public UserEntity saveOrUpdateThirdInfo(String thirdType, String openId, String asString) {
		// TODO Auto-generated method stub
		return null;
	}
	
	public UserEntity findByMobile(String mobile){
		return userRepo.findByMobile(mobile);
	}

	public UserEntity getById(String userId) {
		return userRepo.getById(userId);
	}
	
	public boolean updateUser(UserEntity user){
		 String id = user.getId();
	     UserEntity userIDB = userRepo.getById(id);
	     String nickName = user.getNickName();
	     String logoUrl = user.getLogoUrl();
	     if(StringUtils.isBlank(nickName)){
	    	 nickName = userIDB.getNickName();
	     }
	     if(StringUtils.isBlank(logoUrl)){
	    	 logoUrl = userIDB.getLogoUrl();
	     }
		 //向腾讯IM注册一个用户
	        TencentRequestVo tencenRequestVo = new TencentRequestVo();
	        tencenRequestVo.setIdentifier(id);
	        tencenRequestVo.setNick(nickName);
	        tencenRequestVo.setFaceUrl(logoUrl);
	        TencentResponseVo tencentResponse = tencentIMService.tencentAccount(tencenRequestVo);
			
	    	return userRepo.updateUser(user);
	    }

	public UserEntity loginByTerm(UserTermDeviceEntity term) {
		UserEntity userInDB = null;
		UserEntity userEntity = userRepo.getByTerm(term);
		if (userEntity == null ) {
			userEntity = new UserEntity();
	        userEntity.setId(idGenerator.nextId());
	        userEntity.setCreatedAt(System.currentTimeMillis());
	        userEntity.setUpdatedAt(System.currentTimeMillis());
	        
	        userEntity.setUserRoleList(Arrays.asList(new UserEntity.Role[] {UserEntity.Role.ANONYMOUS}));
	        userEntity.setTermDevice(term);
	        userEntity.setAccount(term.getMobileImei());
	        userEntity.setRegMethod(UserEntity.RegMethod.ANONYMOUS);
	        userEntity.setAnonymous(true);
	        userInDB = userEntity;
	        userRepo.save(userEntity);
		}else{
			userInDB =  new UserEntity();
			userInDB.setId(idGenerator.nextId());
			userInDB.setCreatedAt(System.currentTimeMillis());
			userInDB.setUpdatedAt(System.currentTimeMillis());
			userInDB.setUserRoleList(Arrays.asList(new UserEntity.Role[] {UserEntity.Role.ANONYMOUS}));
			userInDB.setTermDevice(term);
			userInDB.setAccount(term.getMobileImei());
			userInDB.setRegMethod(UserEntity.RegMethod.ANONYMOUS);
			userInDB.setAnonymous(true);
			userEntity.setTermDevice(term);
		    userRepo.save(userEntity);
		}
		
		return userInDB;
	}

}
